Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.SharePoint.WebPartPages
Imports Microsoft.Office.Server
Imports Microsoft.Office.Server.Search.Query
Imports System.Xml.Serialization
Imports ASPNET_WebPart = System.Web.UI.WebControls.WebParts

Namespace Microsoft.SharePoint.Search.Custom


    ''' <summary>
    ''' Web part to execute the actual wildcard search.
    ''' Most of what was done is documented in the SDK and MSDN sites. 
    ''' Below are several links related to this information.
    ''' <para>
    ''' <list type="bullet">
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms469765.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms551453.aspx</item>
    ''' <item>http://msdn.microsoft.com/msdnmag/issues/06/02/BasicInstincts/</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms499375.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms546216.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/bb219479.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms519321.aspx</item>
    ''' </list>
    ''' </para>
    ''' </summary>
    <XmlRoot(Namespace:="MicrosoftCustomSearch")> _
    <DefaultProperty("Text"), ToolboxData("<{0}:MicrosoftSearchControl runat=server></{0}:MicrosoftSearchControl>")> _
    Public Class MicrosoftCustomSearchControl
        Inherits WebPart 'Inherit from WebPart Class
        Implements IXMLData 'Implement data transfer interface for WebPart connection.


        ''' <summary>
        ''' Button to execute search
        ''' </summary>
        Dim WithEvents cmdSearch As Button

        ''' <summary>
        ''' Search Textbox
        ''' </summary>
        Dim txtQueryText As TextBox

        ''' <summary>
        ''' Control to show messages
        ''' </summary>
        Dim lblQueryResult As Label

#If DEBUG Then
        ''' <summary>
        ''' List of datagrids showing in the control
        ''' Used primarily when debugging is turned on.
        ''' </summary>
        Dim grdList As List(Of DataGrid) = New List(Of DataGrid)
#End If

        ''' <summary>
        ''' Dataset to store resulting data from query
        ''' </summary>
        Dim resultDS As DataSet = New DataSet()

        ''' <summary>
        ''' Deafult columns returned if a 
        ''' blank update to the search columns is set.
        ''' </summary>
        Const _defaultSearchColumns As String = "WorkId, rank, RankDetail, title, author, Size, path, Description, Write, " _
            & "SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, " _
            & "ContentClass, IsDocument, PictureThumbnailURL, PictureURL, " _
            & "Firstname, LastName, Account, AccountName, Email, " _
            & "AboutMe, Fax, Manager, SipAddress, skills, department, " _
            & "WorkAddress, WorkCity, WorkCountry, WorkPhone, WorkState, WorkZip, WorkEmail, " _
            & "JobTitle, Responsibilities"

        ''' <summary>
        ''' String to store the columns returned
        ''' </summary>
        ''' <remarks>Allows to dynamically control what 
        ''' columns are returned in the search.</remarks>
        Dim _searchColumns As String = _defaultSearchColumns

        '''Property to change the columns returned. The value 
        '''is only stored in the Shared Storage. 
        '''It can't be personalized.
        <Browsable(True), Category("Search Information")> _
        <DefaultValue(""), WebPartStorage(Storage.Shared)> _
        <FriendlyName("Columns"), Description("Search Columns to return (based on Index Fields). Comma seperated list.")> _
        Public Property SearchColumns() As String
            Get
                Return Me._searchColumns
            End Get
            Set(ByVal value As String)
                If value <> String.Empty Then
                    Me._searchColumns = value
                Else
                    Me._searchColumns = _defaultSearchColumns
                End If

            End Set
        End Property

        ''' <summary>
        ''' Method to create child controls when needed.
        ''' </summary>
        ''' <remarks>All the basic controls are created at this level.</remarks>
        Protected Overrides Sub CreateChildControls()

            'Clear out any existing controls
            Controls.Clear()

            'Create search Textbox
            txtQueryText = New TextBox()
            Me.Controls.Add(txtQueryText)

            'Create Search button
            cmdSearch = New Button()
            cmdSearch.Text = "Start Search"

            'Register event handler for button click.
            AddHandler cmdSearch.Click, AddressOf Me.cmdSearch_Click
            Me.Controls.Add(cmdSearch)

            'Create no result label
            lblQueryResult = New Label()
            Me.Controls.Add(lblQueryResult)

        End Sub

        ''' <summary>
        ''' When search is clicked, handle event and show results
        ''' </summary>
        ''' <param name="sender">Control Sendind the event</param>
        ''' <param name="e">Event parameters</param>
        ''' <remarks>This method is fired when the user
        ''' clicks the button for search. This method fills a dataset
        ''' and allows the results to be returned as XML in the interface.
        ''' First the titleNameQueryExecute is fired then 
        ''' the fullTextQueryExecute.</remarks>
        Sub cmdSearch_Click(ByVal sender As Object, ByVal e As EventArgs)

            If (txtQueryText.Text <> String.Empty) Then
                'Clear the DataSet to receive new data.
                resultDS.Clear()
                resultDS.Tables.Clear()
                resultDS.DataSetName = "ResultSet"
                Me.checkColumns()

                'Run the search query based on title, 
                'first name, and last name.
                titleNameQueryExecute(txtQueryText.Text)

                'Run the search query based on 
                'all attributes in search
                fullTextQueryExecute(txtQueryText.Text)
                'Run the search query based on 
                'all attributes in search
                'freeTextQueryExecute(txtQueryText.Text)

#If DEBUG Then
                'If in Debug mode, Show a grid of the 
                'relevant results returned
                fillResultsGrid(resultDS)
#End If
            Else

                lblQueryResult.Text = "You must enter a search word."

            End If

        End Sub

        ''' <summary>
        ''' Method to search the index for items that match on 
        ''' any field for the query terms.
        ''' </summary>
        ''' <param name="strQueryText">Search Terms to look for</param>
        ''' <remarks>This method uses the FullTextSQLQuery syntax to do a
        ''' Freetext search on fields.</remarks>
        Private Sub freeTextQueryExecute(ByVal strQueryText As String)

            'Create the FullTextSqlQuery object for searching the index
            Dim kRequest As FullTextSqlQuery = New FullTextSqlQuery(ServerContext.Current)

            'Prepare the string to use wildcards
            Dim strQuery As String = "'" & strQueryText.Replace("'", "''") & "'"

            'Output the search text to the Trace Listeners
            System.Diagnostics.Trace.TraceInformation("The Search text: " & strQuery)

            'Set the query text to return columns and search appropriate fields.
            'The fields are based on what's indexed in the search settings.
            kRequest.QueryText = "select " & Me._searchColumns & " FROM Scope() WHERE (""scope""='All Sites' " _
            & "OR ""scope""='People') AND FREETEXT(*," & strQuery & ") ORDER BY Rank DESC"

            'Write the query to the Trace listeners
            System.Diagnostics.Trace.TraceInformation("The Query text: " & kRequest.QueryText)
            System.Diagnostics.Trace.Flush()

            'Return all result types except best bets
            kRequest.ResultTypes = ResultType.HighConfidenceResults Or ResultType.DefinitionResults Or ResultType.RelevantResults

            'Get the result table collection from the query
            Dim resultTbls As ResultTableCollection
            Try
                resultTbls = kRequest.Execute()

            Catch ex As Exception
                'Write error out to trace listener
                System.Diagnostics.Trace.TraceError("Exception: " & Environment.NewLine & ex.ToString())
                resultTbls = Nothing
                Exit Sub
            Finally
                'Flush trace statements out to listeners
                System.Diagnostics.Trace.Flush()
            End Try

            'Write the type of tables and number of entries returned to
            'the trace listeners
            System.Diagnostics.Trace.TraceInformation("Result Tables Returned")
            For Each resulttbl As ResultTable In resultTbls
                System.Diagnostics.Trace.TraceInformation("ResultType: " & resulttbl.ResultType.ToString())
                System.Diagnostics.Trace.TraceInformation("Rows Returned: " & resulttbl.RowCount.ToString() & Environment.NewLine)
            Next

            'For each table type write the results to the dataset if they are not empty and exists
            If (CType(ResultType.HighConfidenceResults, Integer) <> 0) And resultTbls.Exists(ResultType.HighConfidenceResults) Then

                Dim tblResult As ResultTable = resultTbls(ResultType.HighConfidenceResults)
                If (tblResult.TotalRows = 0) Then

                    lblQueryResult.Text = "No Search Results Returned."

                Else
                    lblQueryResult.Text = String.Empty
                    ReadHighResultTable(tblResult)
                End If

            End If

            If (CType(ResultType.RelevantResults, Integer) <> 0) And resultTbls.Exists(ResultType.RelevantResults) Then

                Dim tblResult As ResultTable = resultTbls(ResultType.RelevantResults)
                If (tblResult.TotalRows = 0) Then

                    lblQueryResult.Text = "No Search Results Returned."

                Else
                    lblQueryResult.Text = String.Empty
                    ReadResultTable(tblResult)
                End If

            End If
        End Sub

        ''' <summary>
        ''' Default ReadResultTable Method modified to use a table name for the dataset
        ''' </summary>
        ''' <param name="rt">Search Result Table</param>
        ''' <remarks>This was modified to use a table name to add to the dataset. 
        ''' Makes this method reusable across the webpart.</remarks>
        Sub ReadResultTable(ByVal rt As ResultTable)

            ReadResultTable("Relevant Results", rt)

        End Sub

        ''' <summary>
        ''' Modified ReadResultTable method to take a table name to 
        ''' store in the dataset. This allows multiple tables to 
        ''' be saved and exported without collisions.
        ''' </summary>
        ''' <param name="tablename">Name of the table to save to the DataSet</param>
        ''' <param name="rt">Search result table to save</param>
        ''' <remarks>This method was modified so that it could be 
        ''' reused to store data into a dataset for exporting.</remarks>
        Sub ReadResultTable(ByVal tablename As String, ByVal rt As ResultTable)

            'Create new table to hold data
            Dim relResultsTbl As DataTable = New DataTable()

            'Name the table the requested name
            relResultsTbl.TableName = tablename

            'Add the new table to the dataset
            resultDS.Tables.Add(relResultsTbl)

            'Load the table with data from the search
            'result table.
            resultDS.Load(rt, LoadOption.OverwriteChanges, relResultsTbl)

        End Sub

        ''' <summary>
        ''' High Probility result table storage.
        ''' </summary>
        ''' <param name="rt">Search result table to store</param>
        ''' <remarks>This is a modified ReadResultTable 
        ''' method to store it as "High Probility" results.</remarks>
        Sub ReadHighResultTable(ByVal rt As ResultTable)

            ReadResultTable("High Results", rt)
        End Sub

        ''' <summary>
        ''' Method to search the index for items that match on the 
        ''' title (combination of first and last name) and directly on 
        ''' First Name and Last Name fields.
        ''' </summary>
        ''' <param name="strQueryText">Search Terms to look for</param>
        ''' <remarks>This method uses the FullTextSQLQuery syntax to do a
        ''' wildcard search on fields. It uses a simple split at spaces 
        ''' to determine words to search on. The split could be more complex 
        ''' by creating a function to search for quotes and so on.</remarks>
        Private Sub titleNameQueryExecute(ByVal strQueryText As String)

            'Create the FullTextSqlQuery object for searching the index
            Dim kRequest As FullTextSqlQuery = New FullTextSqlQuery(ServerContext.Current)

            'Prepare the string to use wildcards
            Dim strQuery As String = "'""" & strQueryText.Replace(" ", "*"" OR """) & "*""'"

            'Output the search text to the Trace Listeners
            System.Diagnostics.Trace.TraceInformation("The Search text: " & strQuery)

            'Set the query text to return columns and search appropriate fields.
            'The fields are based on what's indexed in the search settings.
            If (strQueryText.Contains(" ")) Then
                kRequest.QueryText = "select " & Me._searchColumns & " FROM Scope() WHERE (" _
                & """scope""='People') AND (CONTAINS(title," & strQuery & ") OR (CONTAINS(firstname," & strQuery & ")" _
                & "AND CONTAINS(lastname," & strQuery & "))) ORDER BY Rank DESC"
            Else
                kRequest.QueryText = "select " & Me._searchColumns & " FROM Scope() WHERE (" _
                & """scope""='People') AND (CONTAINS(title," & strQuery & ") OR CONTAINS(firstname," & strQuery & ")" _
                & "OR CONTAINS(lastname," & strQuery & ")) ORDER BY Rank DESC"
            End If

            'Write the query to the Trace listeners
            System.Diagnostics.Trace.TraceInformation("The Query text: " & kRequest.QueryText)
            System.Diagnostics.Trace.Flush()

            'Return all result types except best bets
            kRequest.ResultTypes = ResultType.HighConfidenceResults Or ResultType.DefinitionResults Or ResultType.RelevantResults

            'Get the result table collection from the query
            Dim resultTbls As ResultTableCollection
            Try
                resultTbls = kRequest.Execute()

            Catch ex As Exception
                'Write error out to trace listener
                System.Diagnostics.Trace.TraceError("Exception: " & Environment.NewLine & ex.ToString())
                resultTbls = Nothing
                Exit Sub
            Finally
                'Flush trace statements out to listeners
                System.Diagnostics.Trace.Flush()
            End Try


            'Write the type of tables and number of entries returned to
            'the trace listeners
            System.Diagnostics.Trace.TraceInformation("Result Tables Returned")
            For Each resulttbl As ResultTable In resultTbls
                System.Diagnostics.Trace.TraceInformation("ResultType: " & resulttbl.ResultType.ToString())
                System.Diagnostics.Trace.TraceInformation("Rows Returned: " & resulttbl.RowCount.ToString() & Environment.NewLine)
            Next

            'For each table type write the results to the dataset if they are not empty and exists
            If (CType(ResultType.HighConfidenceResults, Integer) <> 0) And resultTbls.Exists(ResultType.HighConfidenceResults) Then

                Dim tblResult As ResultTable = resultTbls(ResultType.HighConfidenceResults)
                If (tblResult.TotalRows = 0) Then

                    lblQueryResult.Text = "No Search Results Returned."

                Else
                    lblQueryResult.Text = String.Empty
                    ReadResultTable("Name Match High", tblResult)
                End If

            End If

            If (CType(ResultType.RelevantResults, Integer) <> 0) And resultTbls.Exists(ResultType.RelevantResults) Then

                Dim tblResult As ResultTable = resultTbls(ResultType.RelevantResults)
                If (tblResult.TotalRows = 0) Then

                    lblQueryResult.Text = "No Search Results Returned."

                Else
                    lblQueryResult.Text = String.Empty
                    ReadResultTable("Name Match Relevant", tblResult)
                End If

            End If
        End Sub

        ''' <summary>
        ''' Method to search the index for items that match on 
        ''' any field for the query terms.
        ''' </summary>
        ''' <param name="strQueryText">Search Terms to look for</param>
        ''' <remarks>This method uses the FullTextSQLQuery syntax to do a
        ''' wildcard search on fields. It uses a simple split at spaces 
        ''' to determine words to search on. The split could be more complex 
        ''' by creating a function to search for quotes and so on.</remarks>
        Private Sub fullTextQueryExecute(ByVal strQueryText As String)

            'Create the FullTextSqlQuery object for searching the index
            Dim kRequest As FullTextSqlQuery = New FullTextSqlQuery(ServerContext.Current)

            'Prepare the string to use wildcards
            Dim strQuery As String = "'""" & strQueryText.Replace(" ", "*"" AND """) & "*""'"

            'Output the search text to the Trace Listeners
            System.Diagnostics.Trace.TraceInformation("The Search text: " & strQuery)

            'Set the query text to return columns and search appropriate fields.
            'The fields are based on what's indexed in the search settings.
            kRequest.QueryText = "select " & Me._searchColumns & " FROM Scope() WHERE (""scope""='All Sites' " _
            & "OR ""scope""='People') AND CONTAINS(*," & strQuery & ") ORDER BY Rank DESC"

            'Write the query to the Trace listeners
            System.Diagnostics.Trace.TraceInformation("The Query text: " & kRequest.QueryText)
            System.Diagnostics.Trace.Flush()

            'Return all result types except best bets
            kRequest.ResultTypes = ResultType.HighConfidenceResults Or ResultType.DefinitionResults Or ResultType.RelevantResults

            'Get the result table collection from the query
            Dim resultTbls As ResultTableCollection
            Try
                resultTbls = kRequest.Execute()

            Catch ex As Exception
                'Write error out to trace listener
                System.Diagnostics.Trace.TraceError("Exception: " & Environment.NewLine & ex.ToString())
                resultTbls = Nothing
                Exit Sub
            Finally
                'Flush trace statements out to listeners
                System.Diagnostics.Trace.Flush()
            End Try

            'Write the type of tables and number of entries returned to
            'the trace listeners
            System.Diagnostics.Trace.TraceInformation("Result Tables Returned")
            For Each resulttbl As ResultTable In resultTbls
                System.Diagnostics.Trace.TraceInformation("ResultType: " & resulttbl.ResultType.ToString())
                System.Diagnostics.Trace.TraceInformation("Rows Returned: " & resulttbl.RowCount.ToString() & Environment.NewLine)
            Next

            'For each table type write the results to the dataset if they are not empty and exists
            If (CType(ResultType.HighConfidenceResults, Integer) <> 0) And resultTbls.Exists(ResultType.HighConfidenceResults) Then

                Dim tblResult As ResultTable = resultTbls(ResultType.HighConfidenceResults)
                If (tblResult.TotalRows = 0) Then

                    lblQueryResult.Text = "No Search Results Returned."

                Else
                    lblQueryResult.Text = String.Empty
                    ReadHighResultTable(tblResult)
                End If

            End If

            If (CType(ResultType.RelevantResults, Integer) <> 0) And resultTbls.Exists(ResultType.RelevantResults) Then

                Dim tblResult As ResultTable = resultTbls(ResultType.RelevantResults)
                If (tblResult.TotalRows = 0) Then

                    lblQueryResult.Text = "No Search Results Returned."

                Else
                    lblQueryResult.Text = String.Empty
                    ReadResultTable(tblResult)
                End If

            End If
        End Sub

#If DEBUG Then
        ''' <summary>
        ''' Method to take the results in the dataset 
        ''' and display a grid with links to each item returned.
        ''' </summary>
        ''' <param name="grdDs">Dataset containing the resulting search
        ''' tables returned</param>
        ''' <remarks>This gird is displayed for debugging purposes.
        ''' When compiled in release mode, this function is 
        ''' not included.</remarks>
        Private Sub fillResultsGrid(ByVal grdDs As DataSet)

            'Clear out the existing grid list
            grdList.Clear()

            'Go through each table in the dataset
            'and show the restuls of the search.
            For Each table As DataTable In grdDs.Tables

                'Sort the default view by descending rank
                table.DefaultView.Sort = "Rank Desc"

                'Create a new grid and add it to the list.
                Dim grdResults = New DataGrid()
                grdList.Add(grdResults)

                'Set the data source for the grid 
                'to be the default view of the table.
                grdResults.DataSource = table.DefaultView

                'Set the display properties for the DataGrid.
                grdResults.GridLines = GridLines.None
                grdResults.CellPadding = 4
                grdResults.Width = Unit.Percentage(100)
                grdResults.ItemStyle.ForeColor = System.Drawing.Color.Black
                grdResults.ItemStyle.BackColor = System.Drawing.Color.AliceBlue
                grdResults.ItemStyle.Font.Size = FontUnit.Smaller
                grdResults.ItemStyle.Font.Name = "Tahoma"
                grdResults.HeaderStyle.BackColor = System.Drawing.Color.Navy
                grdResults.HeaderStyle.ForeColor = System.Drawing.Color.White
                grdResults.HeaderStyle.Font.Bold = True
                grdResults.HeaderStyle.Font.Name = "Tahoma"
                grdResults.HeaderStyle.Font.Size = FontUnit.Medium

                'Turn off AutoGenerate for the columns, so that the DataGrid
                'doesn() 't automatically bind to all of the columns
                'in the search results set.
                'Then create and configure only the columns you want to
                'include in the DataGrid.
                '
                grdResults.AutoGenerateColumns = False

                'Add the rank column
                Dim colRank As BoundColumn = New BoundColumn()
                colRank.DataField = "Rank"
                colRank.HeaderText = "Rank"
                grdResults.Columns.Add(colRank)

                'Add the link to the item found
                Dim colTitle As HyperLinkColumn = New HyperLinkColumn()
                colTitle.DataTextField = "Title"
                colTitle.HeaderText = "Title"
                colTitle.DataNavigateUrlField = "Path"
                grdResults.Columns.Add(colTitle)

                'Add the description
                Dim colDescription As BoundColumn = New BoundColumn()
                colDescription.DataField = "Description"
                colDescription.HeaderText = "Description"
                grdResults.Columns.Add(colDescription)

                'Add the author
                Dim colAuthor As BoundColumn = New BoundColumn()
                colAuthor.DataField = "Author"
                colAuthor.HeaderText = "Author"
                grdResults.Columns.Add(colAuthor)

                'Bind the data to the DataGrid
                grdResults.DataBind()

                'Add the DataGrid to the controls
                Controls.Add(grdResults)

            Next

        End Sub
#End If


        ''' <summary>
        ''' Returns the provider for the consumers to use.
        ''' In this case, this webpart is the provider and 
        ''' the consumers use this instance to get relevant XML data.
        ''' </summary>
        ''' <returns>Interface of XMLData (this webpart)</returns>
        ''' <remarks>Much of how to do this is covered int the SDK and MSDN</remarks>
        <ASPNET_WebPart.ConnectionProvider("XML Consumer", "IXMLData")> _
        Public Function ItemProvider() As IXMLData
            Return (Me)
        End Function

        ''' <summary>
        ''' This is the implementation of the interface
        ''' to share XML data to other WebParts.
        ''' This method converts escaped XML strings for certain fields
        ''' to true XML before sending.
        ''' </summary>
        Public ReadOnly Property XMLData() As System.Xml.XmlDocument Implements IXMLData.XMLData
            Get

                'Document to return through interface
                Dim returnDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()
                Try

                    'Load the dataset XML information
                    returnDoc.LoadXml(resultDS.GetXml())

                    'Create a XPath navigator to go through Nodes
                    Dim pathnav As System.Xml.XPath.XPathNavigator = returnDoc.CreateNavigator()

                    'Convert Node to standard XML instead of escaped XML string
                    For Each item As System.Xml.XPath.XPathNavigator In pathnav.Select("/*/*/HITHIGHLIGHTEDSUMMARY")
                        item.InnerXml = item.InnerXml.Replace("&lt;", "<").Replace("&gt;", ">")
                        System.Diagnostics.Trace.TraceInformation("The XML item text: " & Environment.NewLine & item.OuterXml)

                    Next

                    'Convert Node to standard XML instead of escaped XML string
                    For Each item As System.Xml.XPath.XPathNavigator In pathnav.Select("/*/*/HITHIGHLIGHTEDPROPERTIES")
                        item.InnerXml = item.InnerXml.Replace("&lt;", "<").Replace("&gt;", ">")
                        System.Diagnostics.Trace.TraceInformation("The XML item text: " & Environment.NewLine & item.OuterXml)

                    Next

                    'Convert Node to standard XML instead of escaped XML string
                    For Each item As System.Xml.XPath.XPathNavigator In pathnav.Select("/*/*/RANKDETAIL")
                        item.InnerXml = "<![CDATA[" & Environment.NewLine & item.InnerXml.Replace("&lt;", "<").Replace("&gt;", ">") & Environment.NewLine & "]]>"
                        'item.InnerXml = Environment.NewLine & item.InnerXml.Replace("&lt;", "<").Replace("&gt;", ">") & Environment.NewLine
                        System.Diagnostics.Trace.TraceInformation("The XML item text: " & Environment.NewLine & item.OuterXml)

                    Next

                    'Write resulting XML to trace listener
                    System.Diagnostics.Trace.TraceInformation("The XML text: " & Environment.NewLine & returnDoc.OuterXml)

                Catch ex As Exception
                    'Write error out to trace listener
                    System.Diagnostics.Trace.TraceError("Exception: " & Environment.NewLine & ex.ToString())
                Finally
                    'Flush trace statements out to listeners
                    System.Diagnostics.Trace.Flush()
                End Try

                'return XML to connected parts
                Return (returnDoc)
            End Get

        End Property

        ''' <summary>
        ''' Check the Columns to verify the 
        ''' default is not needed.
        ''' </summary>
        Sub checkColumns()

            If Me._searchColumns = String.Empty Then

                Me._searchColumns = _defaultSearchColumns

            End If


        End Sub


    End Class



End Namespace

